package com.nageoffer.onecoupon.merchant.admin.dao.sharding;

import org.apache.shardingsphere.sharding.api.sharding.standard.PreciseShardingValue;
import org.apache.shardingsphere.sharding.api.sharding.standard.RangeShardingValue;
import org.apache.shardingsphere.sharding.api.sharding.standard.StandardShardingAlgorithm;

import java.util.Collection;
import java.util.List;
import java.util.Properties;

/**
 * 自定义分表算法：基于哈希取模的分表策略
 */
public class TableHashModShardingAlgorithm implements StandardShardingAlgorithm<Long> {

    @Override
    public void init(Properties props) {
        // 初始化方法，可以加载配置
    }

    /**
     * 根据分片列的值进行精确分片，返回对应的目标名称。
     *
     * @param availableTargetNames 可用的目标名称集合，表示所有可能的分片目标。
     * @param shardingValue 包含分片列的值，用于确定分片的目标。
     * @return 返回与分片列值对应的目标名称。
     * @throws IllegalArgumentException 如果未找到与分片列值对应的目标，则抛出此异常。
     */
    @Override
    public String doSharding(Collection<String> availableTargetNames, PreciseShardingValue<Long> shardingValue) {
        // 获取分片列的值
        long shopNumber = shardingValue.getValue();

        // 计算哈希值并取模，确定目标索引
        int shardingCount = availableTargetNames.size();
        System.out.println(shopNumber +"+"+shardingCount);
        int mod = (int) hashShardingValue(shopNumber) % shardingCount;

        // 遍历可用目标名称集合，找到与计算出的索引匹配的目标名称
        int index = 0;
        for (String targetName : availableTargetNames) {
            if (index == mod) {
                return targetName;
            }
            index++;
        }

        // 如果未找到匹配的目标名称，抛出异常
        throw new IllegalArgumentException("No target found for value: " + shopNumber);
    }
    private long hashShardingValue(final Comparable<?> shardingValue) {
        return Math.abs((long) shardingValue.hashCode());
    }
    @Override
    public Collection<String> doSharding(Collection<String> collection, RangeShardingValue<Long> rangeShardingValue) {
        return  List.of();
    }

    @Override
    public String getType() {
        return "CLASS_BASED";
    }
}
